Ext.namespace('Ext.browser');

Ext.browser.panel = Ext.extend(Ext.Panel, {
    id: 'tracks_panel',
    highlight: {
        event: false
    },
    popups: [],
    update: new Ext.util.DelayedTask(function() {
        Ext.getCmp('tracks_panel').display(true);
    },
    this),
 
    initComponent: function() {
        //console.log('init browser')
        //console.log(this.optional_tracks)
        optional_tracks = []
        this.popups = []

        for(i in config[current_genome].tracks) {
            track = config[current_genome].tracks[i]
            if (!track.always_show) {
                optional_tracks.push({
                    id: track.id,
                    name: track.id,
                    boxLabel: track.name,
                    checked: track.checked,
                    stateful: true
                });
            }
        }

        var checkboxgroup = new Ext.form.CheckboxGroup({
            id: 'trackForm',
            fieldLabel: 'Other Tracks'

            + '<img src="images/Information.png" class="tip" id="other_tracks_tip"/>',
            columns: 1,
            items: optional_tracks
        })

        var tracks_form = new Ext.form.FormPanel({
            //title:"Search",
            frame: true,

            autoHeight: true,
            labelAlign: 'top',
            waitMsgTarget: true,
            items: [checkboxgroup]
        });

        if(Ext.getCmp('select_tracks_popup') != undefined)
            Ext.getCmp('select_tracks_popup').destroy()
        this.tracks_win = new Ext.Window({
            title: "Tracks",
            id: 'select_tracks_popup',
            ctCls: 'myPopup',
            closable: true,
            closeAction: 'hide',
            layout: 'anchor',
            autoHeight: true,
            autoWidth: true,
            stateful: true,
            plain: true,
            items: tracks_form
        });
        this.tracks_win.show()
        this.tracks_win.hide()
        if(Ext.getCmp('browserHelpPopout') != undefined)
            Ext.getCmp('browserHelpPopout').destroy()

        this.helpWin = new Ext.Window({
            title: "Browser Help",
            id: 'browserHelpPopout',
            overCls: 'myPopup',
            closable: true,
            closeAction: 'hide',
            layout: 'anchor',
            autoHeight: true,
            width: 300,
            stateful: false,
            plain: true,
            html: config[current_genome].helpText.browserTip
        });
 
        
        
        Ext.apply(this, {
            title: 'Browser',
            margins: '0 0 0 0',
            //tbar: mainTBar,
            tbar: new Ext.Toolbar({
                xtype: 'tbspacer',
                items: [{
                    xtype: 'button',
                    text: 'Browser',
                    id: 'browser_btn',
                    //tooltip:'Use shift+click to highlight a region',
                    icon: 'images/Information.png',
                    cls: 'x-btn-text-icon',
                    handler: function()
                    {
                        if (Ext.getCmp('browserHelpPopout').isVisible())
                            Ext.getCmp('browserHelpPopout').hide();
                        else
                            Ext.getCmp('browserHelpPopout').show();
                    },
                    scope:this

                },
                '-',
                {
                    xtype: 'button',
                    text: 'Tracks',
                    id: 'select_tracks',
                    icon: 'images/hist2.png',
                    cls: 'x-btn-text-icon',
                    tooltip: 'Select Tracks to visualize',
                    handler: function()
                    {
                        if (Ext.getCmp('select_tracks_popup').isVisible())
                            Ext.getCmp('select_tracks_popup').hide();
                        else
                            Ext.getCmp('select_tracks_popup').show();
                    },
                    scope:this
                },
                {
                    xtype: 'button',
                    text: 'Zoom In',
                    id: 'zoom_in',
                    icon: 'images/magnifier_zoom_in.png',
                    cls: 'x-btn-text-icon',
                    tooltip: 'Zoom in by 50%. If a section is highlighted zoom highlighted region',
                    scope: this,
                    handler: function() {
                        this.move('in')
                    }
                },
                {
                    xtype: 'button',
                    text: 'Zoom Out',
                    tooltip: 'Zoom in by 50%. Click multiple times to zoom out more.',
                    id: 'zoom_out',
                    icon: 'images/magifier_zoom_out.png',
                    cls: 'x-btn-text-icon',
                    scope: this,
                    handler: function() {
                        this.move('out')
                    }
                },
                {
                    xtype: 'button',
                    text: 'Backward',
                    tooltip: 'Move left by 50%',
                    icon: 'images/arrow_left.png',
                    cls: 'x-btn-text-icon',
                    scope: this,
                    handler: function() {
                        this.move('backward')
                    }
                },
                {
                    xtype: 'button',
                    text: 'Forward',
                    tooltip: 'Move right by 50%',
                    icon: 'images/arrow_right.png',
                    cls: 'x-btn-text-icon',
                    scope: this,
                    handler: function() {
                        this.move('forward')
                    }
                },
                '-', '    ',
                {
                    xtype: 'tbtext',
                    text: '',
                    id: 'browserLocation'
                },
                '-', '   ',
                {
                    xtype: 'tbtext',
                    text: '',
                    id: 'browserLocationSize'
                }
                ]
            }),

            autoScroll: true,
            split: true,
            //title: 'Browser',
            height: 400,
            id: 'tracks_panel',
            html: '<div id="highlight"></div><div id="tracks"><div id="genome_tracks"></div><div id="summary_tracks"></div><div id="sample_tracks"></div></div>'

        });
        Ext.browser.panel.superclass.initComponent.apply(this, arguments);

        checkboxgroup.on('change', function() {this.display(false)}, this)

    },
    afterRender: function() {
        Ext.browser.panel.superclass.afterRender.apply(this, arguments);
        this.track_mask = new Ext.LoadMask('tracks_panel', {
            msg: "Loading",
            id: 'track_mask'
        });

        Ext.get('tracks').on({
            'mousedown': {
                fn: this.onDown,
                stopPropagation: true,
                scope: this,
                stopEvent: true
            },
            'mousemove': {
                preventDefault: true,
                scope: this,
                fn: this.onMouseMove
            },
            'mouseup': {
                stopPropagation: true,
                stopEvent: true,
                scope: this,
                fn: this.onUp
            }
        },
        this);

        Ext.get('highlight').on({
            'mousedown': {
                fn: this.onDown,
                stopPropagation: true,
                scope: this,
                stopEvent: true

            },
            'mousemove': {
                preventDefault: true,
                scope: this,
                fn: this.onMouseMove
            },
            'mouseup': {
                stopPropagation: true,
                stopEvent: true,
                scope: this,
                fn: this.onUp
            }
        },
        this);
        Ext.get('other_tracks_tip').on('click',
        function(ee) {
            if(Ext.getCmp('otherTracksTipPopout') != undefined)
                return;
            this.trackTips = new Ext.Window({
                title: "Tracks Help",
                id: 'otherTracksTipPopout',
                ctCls: 'myPopup',
                closable: true,
                layout: 'anchor',
                autoHeight: true,
                autoWidth: true,
                x: ee.xy[0],
                y: ee.xy[1],
                stateful: false,
                plain: true,
                html: config[current_genome].helpText.otherTracksTip
            });
            this.trackTips.show(this);
        },
        this);



    },
    cleanUp: function() {
//        console.log('a')
        this.tracks_win.hide()
        this.helpWin.hide();
        if(this.trackTips != undefined)
            this.trackTips.hide();
        Ext.each(this.popups,
            function(x) {
                x.destroy()
            })
            this.popups = [];
        
    },
    display: function(reset) {
    //console.log('display')
        if (Ext.lib.Ajax.queueManager.getQueue('tracks')) {
            Ext.lib.Ajax.queueManager.getQueue('tracks').clear();
            pendingRequests = 0;

        }
        if (current_loc) {
            var len = current_loc.stop - current_loc.start;
            if (len >= 50000)
            Ext.lib.Ajax.maxConcurrentRequests = 0;
            else if (len < 50000 & len > 10000)
            Ext.lib.Ajax.maxConcurrentRequests = 1;
            else
            Ext.lib.Ajax.maxConcurrentRequests = 5;
        }
        if (!current_loc) {
            var dh = Ext.DomHelper;
            dh.overwrite('genome_tracks', '');
            dh.overwrite('sample_tracks', '');
            dh.overwrite('summary_tracks', '');
            Ext.get('highlight').hide();
            this.highlight.set = false;
            Ext.each(this.popups,
            function(x) {
                x.destroy()
            })
            this.popups = [];
            this.setLocationText(true);
            return;
        }
        if (reset == null)
        reset = false;
        if (reset) {
            //console.log('reset')
            var dh = Ext.DomHelper;
            dh.overwrite('genome_tracks', '');
            dh.overwrite('sample_tracks', '');
            dh.overwrite('summary_tracks', '');
            Ext.get('highlight').hide();
            this.highlight.set = false;
            Ext.each(this.popups,
            function(x) {
                x.destroy()
            })
            this.popups = [];

            this.setLocationText();


        }

        for(i in config[current_genome].tracks) {
            track = config[current_genome].tracks[i]
            if (track.type!='genome_tracks') continue;
            if (track.always_show) {
                this.track_request(track, current_loc);
            } else {
                if (!Ext.getCmp(track.id).checked & Ext.get('div_' + track.id) != undefined) {
                    Ext.get('div_' + track.id).remove();
                    continue;
                }
                if (Ext.getCmp(track.id).checked & Ext.get('div_' + track.id) == undefined) {
                    this.track_request(track, current_loc);
                }
            }
        }
        
        var needToUpdateSummaries = false
        
        selected_tracks = sampleGrid.selected_tracks;
        var existing_tracks = Ext.query('#sample_tracks .track_div');
        for (var i = 0; i < existing_tracks.length; i++) {
            //var id = existing_tracks[i].id.split('_')[1]
            var id = existing_tracks[i].getAttribute('value')
            if (selected_tracks.indexOf(id) == -1) {
                // console.log('remove:' + id)
                Ext.get(existing_tracks[i]).remove();
                needToUpdateSummaries = true                
            }
        }

        for (var i = 0; i < selected_tracks.length; i++) {

            for(tt in config[current_genome].tracks) {
                track = config[current_genome].tracks[tt]
                
                if(track.type!='sample_tracks') continue;
                canvas_id = 'canvas_' + track.id + '_' + selected_tracks[i];
                
                if(track.always_show == true & Ext.get(canvas_id) == undefined) {
                    //console.log('always')
                    this.track_request(track, current_loc);
                } else {
                    //console.log('some times')
                    if (!Ext.getCmp(track.id).checked & Ext.get(canvas_id) != undefined) {
                        //console.log('need to remove')
                        Ext.get(canvas_id).remove();
                        needToUpdateSummaries = true                
                        continue;
                    } 
                    if (Ext.getCmp(track.id).checked & Ext.get(canvas_id) == undefined) {
                        //console.log('need to add')
                        track.sample_id = selected_tracks[i];
                        var t = cloneObj(track);
                        this.track_request(t, current_loc);
                    }
                }
            }
        }
        if(needToUpdateSummaries)
            this.update_summaries();
    },
    ajax_call: function(track, current_loc) {
        var len = current_loc.stop - current_loc.start;
        var pixel_size = Math.round(len / 500);
        if (pixel_size < 1) pixel_size = 1;

        var params = {
            start: current_loc.start,
            stop: current_loc.stop,
            chr_name: current_loc.chr_name,
            pixel_size: pixel_size
        };
        Ext.applyIf(params, track.additional_params);
        if (track.sample_id != undefined) {
            params['sample_id'] = track.sample_id;
        }
        //var url = track.url + '?' + Ext.urlEncode(params);
        var p = cloneObj(params);
        p['url'] = track.url;
        //console.log(Ext.encode(p))
        var cached = false;
        var index;
        for (var i = 0; i < ajaxRequests.length; i++) {
            if (Ext.encode(p) == Ext.encode(ajaxRequests[i])) {
                cached = true;
                index = i;
                break;
            }
        }

        if (!cached) {
            pendingRequests++;
            //console.log(pendingRequests)
            Ext.Ajax.request({
                scope: this,
                url: track.url,
                method: 'GET',
								xdomain:true,
                timeout: 300000,
                params: params,
                queue: {
                    name: 'tracks',
                    priority: 5
                },
                success: function(response, opts) {
                    pendingRequests -= 1;
                    if (pendingRequests == 0) {
                        this.track_mask.hide();
                    }
                    if (response.responseText.length == 0) {
                        return;
                    }
                    ajaxRequests.push(p);
                    ajaxData[ajaxRequests.length - 1] = Ext.decode(response.responseText);
                    eval('this.' + track.func
                    + '(track,current_loc,ajaxData[ajaxRequests.length - 1],pixel_size)');
                    this.update_summaries();

                },
                failure: function(response, opts) {
                    console.log('track failed')
                    pendingRequests -= 1;
                    if (pendingRequests == 0) {
                        this.track_mask.hide();
                    }
                }

            });
        }
        else {
            if (pendingRequests == 0)
            this.track_mask.hide();
            eval('this.' + track.func + '(track,current_loc,ajaxData[index],pixel_size)');
            this.update_summaries();
        }
    },
    track_request: function(track, current_loc) {
        this.track_mask.show();
        if (track.url != undefined) {
            this.ajax_call(track, current_loc);
        }
        else {
            //console.log('ccc')
            eval('this.' + track.process_function + '(track,current_loc)');
            this.track_mask.hide();
        }

    },
    update_summaries: function() {
        // console.log('selected=' + selected_tracks.length);
        // console.log('pendingRequests=' + pendingRequests);
        if (pendingRequests != 0 | selected_tracks.length == 0) return;
        // console.log('bbbb');
        for(i in config[current_genome].tracks) {
            track = config[current_genome].tracks[i]
            if(track.type!='summary_tracks') continue;
            
            if(track.always_show) {
                if (Ext.get('div_' + track.id) != undefined)
                    Ext.get('div_' + track.id).remove();
                this.track_request(track, current_loc);
            } else {
                if (!Ext.getCmp(track.id).checked & Ext.get('div_' + track.id) != undefined) {
                    Ext.get('div_' + track.id).remove();
                    continue;
                }
                if (Ext.getCmp(track.id).checked) {
                    // console.log('is checked')
                    // console.log(Ext.get('div_' + track.id))
                    if (Ext.get('div_' + track.id) != undefined)
                        Ext.get('div_' + track.id).remove();
                    this.track_request(track, current_loc);
                }

            }
        }
    },

    move: function(way) {
        move_factor = 4;
        if (current_loc == null)
        return;
        var len = current_loc.stop - current_loc.start;
        var width = Ext.getCmp('tracks_panel').getInnerWidth();
        if (way == 'in') {
            var start = current_loc.start;
            //alert(image_select_pos.set);
            if (this.highlight.set) {
                current_loc.start = parseInt(parseInt(start)
                + (len * (this.highlight.start_coord / width)));
                current_loc.stop = parseInt(parseInt(start)
                + (len * (this.highlight.stop_coord / width)));
                image_select_pos.set = false;
                this.update.delay(0);
            } else {
                current_loc.start = parseInt(parseInt(current_loc.start) + (len / move_factor));
                current_loc.stop = parseInt(parseInt(current_loc.stop) - (len / move_factor));
                this.update.delay(500);
            }
        }
        else if (way == 'out') {
            current_loc.start = parseInt(parseInt(current_loc.start) - (len / move_factor));
            current_loc.stop = parseInt(parseInt(current_loc.stop) + (len / move_factor));
            this.update.delay(500);
        }

        else if (way == 'forward') {
            current_loc.start = parseInt(parseInt(current_loc.start) + (len / move_factor));
            current_loc.stop = parseInt(parseInt(current_loc.stop) + (len / move_factor));
            this.update.delay(500);
        }
        else if (way == 'backward') {
            current_loc.start = parseInt(parseInt(current_loc.start) - (len / move_factor));
            current_loc.stop = parseInt(parseInt(current_loc.stop) - (len / move_factor));
            this.update.delay(500);
        }
        if(current_loc.start < 0)
            current_loc.start = 0;
        if(current_loc.stop < 0)
            current_log.stop = 0;
            
        this.setLocationText();
    },
    setLocationText: function(reset) {
        if (reset) {
            Ext.getCmp('browserLocation').setText('');
            Ext.getCmp('browserLocationSize').setText('');
            return;
        }
        var len_out;
        var len = current_loc.stop - current_loc.start;

        if (len < 1000) {
            len_out = len + 'bp';
        }
        else if (len >= 1000 & len < 1000000) {
            len_out = len / 1000 + 'Kb';
        }
        else {
            len_out = len / 1000000 + 'Mb';
        }
        Ext.getCmp('browserLocation').setText('<b>Location:</b> ' + current_loc.chr_name + ':' + current_loc.start + '..' + current_loc.stop);
        Ext.getCmp('browserLocationSize').setText('<b>Region Size:</b> ' + len_out);
    },
    onMouseMove: function(ee) {
        if (!this.highlight.event) return;
        if (!ee.hasModifier())
        return;
        //console.dir(ee.xy);
        //alert(mainTabPanel.body.getTop());
        //alert(highlight.start + highlight.stop);
        Ext.getCmp('tracks_panel').highlight.stop = ee.xy[0];
        //alert(highlight.start + ' ' + highlight.stop);
        //console.dir(highlight);
        var height;
        var width;
        if (Ext.get('tracks').getHeight() < this.body.getHeight()) {
            height = this.body.getHeight() - 5;
        } else {
            height = Ext.get('tracks').getHeight();
        }
        if (this.highlight.start > this.highlight.stop) {
            width = this.highlight.start - this.highlight.stop;
            left = this.highlight.stop - Ext.get('tracks').getLeft();
        } else {
            width = this.highlight.stop - this.highlight.start;
            left = this.highlight.start - Ext.get('tracks').getLeft();
        }

        Ext.get('highlight').show();


        Ext.get('highlight').applyStyles(
        "border: medium none ; "
        + "background: blue none repeat scroll 0% 0%;"
        + "position:absolute; "
        + "z-index: 1; opacity: 0.3; text-align: center;"
        + 'top:0px'
        + ';left:' + left
        + ';height:' + height + 'px'
        + ';width:' + width);



    },
    onDown: function(evt) {
        //console.dir(evt);
        Ext.get('highlight').hide();
        if (Ext.get('highlight_popout') != undefined) {
            Ext.get('highlight_popout').remove()
        }

        if (!evt.hasModifier())
        return;
        this.highlight.start = evt.xy[0];
        this.highlight.event = true;
        this.highlight.set = false;

    },
    onUp: function(evt) {
        highlight = this.highlight
        if (Math.abs(highlight.start - highlight.stop) == 0) {
            Ext.get('highlight').hide();
            return;
        }
        if (!evt.hasModifier())
        return;
        highlight.stop = evt.xy[0];
        highlight.event = false;
        if (highlight.start > highlight.stop) {
            var a = highlight.start;
            highlight.start = highlight.stop;
            highlight.stop = a;
        }
        highlight.set = true;
        highlight.start_coord = highlight.start - Ext.get('tracks').getLeft();
        highlight.stop_coord = highlight.stop - Ext.get('tracks').getLeft();


        if (Ext.get('highlight_popout') != undefined) {
            Ext.get('highlight_popout').remove()
        }

        var win = new Ext.Window({
            title: 'Selected Region',
            id: 'highlight_popout',
            closable: true,
            x: evt.xy[0],
            y: evt.xy[1],
            scope: this,
            plain: true,
            width: 130,
            layout: 'anchor',
            stateful: false,
            items: [{
                xtype: 'button',
                text: 'Count Reads',
                icon: 'images/sum.png',
                anchor: '100%',
                scope: this,
                handler: Ext.getCmp('tracks_panel').count_reads
            },
            {
                xtype: 'button',
                text: 'Zoom In',
                anchor: '100%',

                icon: 'images/magnifier_zoom_in.png',
                handler: function()
                {

                    Ext.getCmp('tracks_panel').move('in')
                }
            }]
        },
        this);

        win.show(this);
        this.popups.push(win);

    },
    count_reads: function() {
        var len = current_loc.stop - current_loc.start;
        var width = Ext.getCmp('tracks_panel').getInnerWidth();

        var start = current_loc.start;
        new_start = parseInt(parseInt(start) + (len * (this.highlight.start_coord / width)));
        new_stop = parseInt(parseInt(start) + (len * (this.highlight.stop_coord / width)));
        get_locations(current_loc.chr_name + ':' + new_start + '..' + new_stop, this.track_mask, false);

    },

    create_track: function(type, track, height, labels) {
        var dh = Ext.DomHelper;
        var label;
        var width = (Ext.getCmp('tracks_panel').getInnerWidth() - 19)
        if (typeof(labels) == 'object') {
            for (var k in labels) {
                label += k + ': ' + labels[k] + ' | ';
                if (k == 'cell_type') break;
            }
        } else {
            label = labels;
        }

        if (type == 'genome_tracks' | type =='summary_tracks') {

            var div_id = 'div_' + track.id;
            var value = track.id;
            var canvas_id = 'canvas_' + track.id;
            if (Ext.get(div_id) == undefined) {
                var before_el = undefined;
                var current_tracks = Ext.query('#' + type + ' .track_div');
                if (current_tracks.length != 0) {
                    for (var i = 0; i < current_tracks.length; i++) {
                        if (track.order < current_tracks[i].getAttribute('order')) {
                            before_el = current_tracks[i];
                            break;
                        }
                    }
                }
                if (before_el != undefined) {
                    dh.insertBefore(before_el, '<div style="margin-bottom:5;margin-top:5;" order=' + track.order
                    + ' class="track_div" id="' + div_id + '" value="' + value + '" width="'
                    + width + '" height="' + height + '">'
                    + '<div style="z-index:1;font-size:.8em;" align="center" id="label_' + track.sample_id + '">'
                    + label
                    + '</div>'
                    + '</div>');
                } else {
                    dh.append(type, '<div style="margin-bottom:5;margin-top:5;" order=' + track.order
                    + ' class="track_div" id="' + div_id + '" value="' + value + '" width="'
                    + width + '" height="' + height + '">'
                    + '<div style="z-index:1;font-size:.8em;" align="center" id="label_' + track.sample_id + '">'
                    + label
                    + '</div>'
                    + '</div>');
                }
            }

            if (Ext.get(canvas_id) == undefined) {
                dh.append(div_id, '<canvas class="' + track.id + '" id="' + canvas_id
                + '" width="' + width + '" height="' + height + '"></canvas>');
            }
        }
        else {
            
            var div_id = 'div_' + track.sample_id.replace(/\./g,'_');
            
            var value = track.sample_id;
            var canvas_id = 'canvas_' + track.id + '_' + track.sample_id;
            var label_div = 'label_' + track.sample_id
            var sample_info = sampleGrid.getStore().getAt(sampleGrid.getStore().find('sample_id', track.sample_id)).data
            var sample_track_label = '';
            for (var k = 0; k < config[current_genome].samples.columns.length; k++) {
                var c = config[current_genome].samples.columns[k]
                if (c.hidden != true)
                sample_track_label += c.header + ': ' + sample_info[c.dataIndex] + ' | ';
            }


            if (Ext.get(div_id) == undefined) {
                dh.append(type, '<div style="margin-bottom:5;margin-top:5;" order=' + track.order
                + ' class="track_div" id="' + div_id + '" value="' + value + '" width="'
                + width + '" height="' + (height + 10) + '"></div>');
                dh.append(div_id, '<div style="z-index:1;font-size:.8em;" align="center" id="+' + label_div + '">'
                + label + ' | ' + sample_track_label + '</div>');
                dh.append(div_id, '<canvas order=' + track.order + ' class="' + track.id + '" id="' + canvas_id
                + '" width="' + width + '" height="' + height + '"></canvas>');
            } else {
                var current_tracks = Ext.query('#' + div_id + ' canvas');
                if (current_tracks.length == 0) {
                    if (Ext.get(canvas_id) == undefined)
                        dh.append(div_id, '<canvas order=' + track.order
                        + ' class="' + track.id + '" id="' + canvas_id
                        + '" width="' + width + '" height="' + height + '"></canvas>');
                } else {
                    for (var i = 0; i < current_tracks.length; i++) {
                        //if (i == 'remove') continue;
                        //current_tracks[i].getAttribute('order');
                        if (track.order < current_tracks[i].getAttribute('order')) {
                            before_el = current_tracks[i];
                            break;
                        }
                    }
                    if (before_el) {
                        if (Ext.get(canvas_id) == undefined)
                        dh.insertBefore(before_el, '<canvas order=' + track.order
                        + ' class="' + track.id + '" id="' + canvas_id
                        + '" width="' + width + '" height="' + height + '"></canvas>');
                    } else {
                        if (Ext.get(canvas_id) == undefined)
                        dh.append(div_id, '<canvas order=' + track.order
                        + ' class="' + track.id + '" id="' + canvas_id
                        + '" width="' + width + '" height="' + height + '"></canvas>');
                    }
                }
            }
        }

        var canvas = document.getElementById(canvas_id);
        if (!canvas.getContext)
        G_vmlCanvasManager.initElement(canvas);

        return {
            canvas_id: canvas_id,
            div: div_id,
            canvas: canvas
        };
    },

    show_gene_models: function(track, loc, gene_models, pixel_size) {

        var dh = Ext.DomHelper;
        var ids = this.create_track(track.type, track, track.height, '');
        var canvas = ids.canvas;
        var ctx = canvas.getContext("2d");

        ctx.font = "'arial'";
        var len = loc.stop - loc.start;
        var width = len / canvas.width;
        var position_tick_line_y = 20;
        var gene_models_height = 10;
        var triangle_length = 100 / width;
        if (triangle_length > 10) triangle_length = 10;
        if (triangle_length < 2) triangle_length = 0;
        var dist_btw_genome_and_model = 5;
        var gene_models_plus_y = position_tick_line_y + 10;

        var genome_line = gene_models_plus_y + gene_models_height + dist_btw_genome_and_model;
        var genome_line_height = 3;

        var gene_models_minus_y = genome_line + genome_line_height + dist_btw_genome_and_model;



        ctx.fillStyle = "rgb(239,239,239)";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "rgb(0,0,0)";
        ctx.fillRect(0, position_tick_line_y, canvas.width, 1);

        ctx.fillRect(0, genome_line, canvas.width, genome_line_height);


        for (var i = loc.start; i <= loc.stop; i++) {
            var start = (i - loc.start) / len * canvas.width;
            if ((i - loc.start) % Math.round(len / 10) == 0) {
                ctx.fillRect(start, position_tick_line_y - 3, 1, 7);
                ctx.textAlign = 'center';
                ctx.fillText(i.toString(), start, position_tick_line_y - 7);
            }
        }
        var colors = [
        'rgb(0,0,255)',
        'rgb(255,255,0)',
        'rgb(0,255,255)',
        'rgb(255,0,255)',
        'rgb(192,192,192)',
        'rgb(109,53,26)',
        'rgb(255,0,127)'
        ]

        for (i in gene_models) {
            if(i == 'remove') return;
            gene_info[gene_models[i][0].gene_id] = {
                genename: gene_models[i][0].genename,
                db_gene_id: gene_models[i][0].db_gene_id
            }
            var start = (gene_models[i][0].start - loc.start) / width;
            var stop = (gene_models[i][(gene_models[i].length - 1)].stop - loc.start) / width;

            dh.insertHtml('afterBegin', Ext.getDom(ids.div),
            '<div id="' + gene_models[i][0].gene_id + '_tip" style="top:' + gene_models_plus_y + ';left:' + (start) +
            ';width:' + (stop - start) + ';height:'
            + (gene_models_height * 3 + dist_btw_genome_and_model * 3) + ';position:absolute;z-index: 9; text-align: center;"></div>')

            var basic_tip = new Ext.ToolTip({
                target: gene_models[i][0].gene_id + '_tip',
                html: gene_models[i][0].genename + "<br> Click to see more info and links",
                trackMouse: true,
                showDelay: 50

            });

            var gene = Ext.get(gene_models[i][0].gene_id + '_tip')


            gene.on('click',
            function(ee) {

                if (ee.hasModifier())
                return;

                var id = ee.getTarget().id.split('_')[0]
                if (Ext.get(id + '_popout') != undefined) {
                    Ext.get(id + '_popout').destroy();
                }
                var buttons = [{
                        xtype: 'button',
                        text: 'Get Read Counts',
                        anchor: '100%',
                        icon: 'images/sum.png',
                        scope: this,
                        handler: function() {
                            get_locations(gene_info[id].genename, this.track_mask, false);
                            win.close()
                        }
                    }]
                if(track.popups != undefined) {
                    for (var p = 0; p < track.popups.length; p++) {
                        var info = track.popups[p]
                        url = info.url.replace(/{DBGENEID}/,gene_info[id].db_gene_id)
                        buttons.push({
                            xtype: 'button',
                            id: info.name,
                            text: info.name,
                            url: url,
                            anchor: '100%',
                            scope: this,
                            icon: info.icon,
                            handler: function(e) {
                                window.open(e.url, '_blank')
                            }
                        })
                    }
                }
                var win = new Ext.Window({
                    title: gene_info[id].genename,
                    id: id + '_popout',
                    overCls: 'myPopup',
                    closable: true,
                    layout: 'anchor',
                    scope: this,
                    width: 130,
                    x: ee.xy[0],
                    y: ee.xy[1],
                    stateful: false,
                    plain: true,
                    items: buttons
                });
                win.show(this);
                this.popups.push(win);
            },
            this);

//            console.log(parseInt(i,36) % 7)
            ctx.fillStyle = colors[parseInt(i,36) % 7];
            for (var j = 0; j < gene_models[i].length; j++) {
                //for(j in gene_models[i]) {
                if (j == 'remove') continue;
                //alert(i + ' ' + j);

                exon = gene_models[i][j];
                if (gene_models[i][parseInt(j) + 1] != undefined) {
                    var next_exon = gene_models[i][parseInt(j) + 1];
                    var next_start = (next_exon.start - loc.start) / width;
                }


                var start = (exon.start - loc.start) / width;
                var stop = (exon.stop - loc.start) / width;

                //console.log([start,stop])
                if (exon.strand == '+') {
                    if (gene_models[i][parseInt(j) + 1] != undefined) {
                        ctx.fillRect(start, gene_models_plus_y, stop - start,
                        gene_models_height);
                        ctx.fillRect(stop,
                        gene_models_plus_y + (gene_models_height / 2),
                        next_start - stop, 2);

                    } else {

                        ctx.beginPath();
                        ctx.moveTo(start, gene_models_plus_y);
                        ctx.lineTo(stop - triangle_length, gene_models_plus_y);
                        ctx.lineTo(stop, gene_models_plus_y + gene_models_height / 2);
                        ctx.lineTo(stop - triangle_length,
                        gene_models_plus_y + gene_models_height);
                        ctx.lineTo(start,
                        gene_models_plus_y + gene_models_height);
                        ctx.fill();

                    }
                }
                else {
                    //console.dir(next_exon);
                    if (gene_models[i][parseInt(j) + 1] != undefined) {
                        ctx.fillRect(stop,
                        gene_models_minus_y + (gene_models_height / 2),
                        next_start - stop, 2);
                    }
                    if (j == 0)
                    {
                        ctx.beginPath();
                        ctx.moveTo(stop,
                        gene_models_minus_y);
                        ctx.lineTo(start + triangle_length,
                        gene_models_minus_y);
                        ctx.lineTo(start,
                        gene_models_minus_y + gene_models_height / 2);
                        ctx.lineTo(start + triangle_length,
                        gene_models_minus_y + gene_models_height);
                        ctx.lineTo(stop,
                        gene_models_minus_y + gene_models_height);
                        ctx.fill();
                    } else {
                        ctx.fillRect(start, gene_models_minus_y, stop - start, gene_models_height);

                    }

                }
            }
        }
    },

    show_coverage: function(track, loc, track_data, pixel_size) {
        var ids = this.create_track(track.type, track, track.height, track.label);


        var canvas = ids.canvas;
        var ctx = canvas.getContext("2d");

        ctx.font = "'arial'";

        var background_y = 0;
        var text_max_x = canvas.width - 100;



        ctx.fillStyle = "rgb(239,239,239)";
        ctx.fillRect(0, background_y, canvas.width, canvas.height - background_y);

        //ctx.fillText('max:'+ track_data.max.toPrecision(5),text_max_x,background_y);
        var len = loc.stop - loc.start;
        var width = canvas.width / len * pixel_size;
        
        var max = 0;
        var type;
//        console.log(track_data.data)
        for (i in track_data.data) {
            //console.log(typeof track_data.data[i])
            if(typeof track_data.data[i] != 'object')
                type = 'not_stranded';
            else
                type = 'stranded';

            break;
        }
//        console.log(type)
        
        if(type == 'not_stranded') {

            var max_height = canvas.height;
            var base_line = canvas.height;
            
            for (i in track_data.data) {
                if (max < (track_data.data[i]))
                max = track_data.data[i];
            }
            for (i in track_data.data) {
                var start = (i - loc.start) / len * canvas.width;
                var h = track_data.data[i];
    
                if (h == 0) continue;
                ctx.fillStyle = "rgb(0, 0, 0)";

                ctx.fillRect(start, base_line - ((h / max) * max_height),
                width, ((h / max) * max_height));

            }            
        } else {     
            var middle_line = ((canvas.height - background_y) / 2) + background_y;
            var max_height = (canvas.height - background_y) / 2;
            var middle_line_width = 1;
            ctx.fillStyle = "rgb(0,0,0)";
            ctx.fillRect(0, middle_line, canvas.width, middle_line_width);
  
            for (i in track_data.data) {
                if (max < (track_data.data[i][0] + track_data.data[i][1]))
                max = track_data.data[i][0] + track_data.data[i][1];
            }
    
            for (i in track_data.data) {
                var start = (i - loc.start) / len * canvas.width;
                var h = track_data.data[i];
                var all = h[0] + h[1];
                if (h[0] + h[1] == 0) continue;
                ctx.fillStyle = "rgb(0, 0, 0)";
                ctx.fillRect(start, middle_line - ((all / max) * max_height),
                width, ((all / max) * max_height));
    
                ctx.fillStyle = "rgb(0, 255, 0)";
                ctx.fillRect(start, middle_line - ((h[0] / max) * max_height),
                width, ((h[0] / max) * max_height));
                ctx.fillStyle = "rgb(255, 0, 0)";
                ctx.fillRect(start, middle_line, width, ((h[1] / max) * max_height));
            }
        }
        var basic_tip = new Ext.ToolTip({
            target: ids.canvas,
            html: "Track scaled to max:" + max,
            trackMouse: true,
            showDelay: 50
        });

    },

   
    show_splice: function(track, loc, splice_data, pixel_size) {

        var y = 5;
        var previous = undefined;
        var splice_height = 3;
        var max_height = 0;
        for (var j = 0; j < splice_data.length; j++) {
            splice = splice_data[j];

            if (previous != undefined) {
                last_splice = splice_data[previous];
                if (parseInt(last_splice['exon2_start']) + parseInt(last_splice['exon2_len'])
                < parseInt(splice['exon1_start']))
                y = 5;
            }
            previous = j;
            splice_data[j].y = y;
            if (max_height < y) {
                max_height = y;
            }
            y += 4;
        }
        var ids = this.create_track(track.type, track, (max_height + 4), '');
        var canvas = ids.canvas
        var ctx = canvas.getContext("2d");
        var len = loc.stop - loc.start;
        var width = len / canvas.width;

        ctx.fillStyle = "rgb(239,239,239)";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        for (var j = 0; j < splice_data.length; j++) {
            var splice = splice_data[j];

            var start1 = (parseInt(splice['exon1_start']) - loc.start) / width;
            var end1 = (parseInt(splice['exon1_start']) + parseInt(splice['exon1_len']) - loc.start) / width;

            var start2 = (parseInt(splice['exon2_start']) - loc.start) / width;
            var end2 = (parseInt(splice['exon2_start']) + parseInt(splice['exon2_len']) - loc.start) / width;

            ctx.fillStyle = "rgb(255, 0, 0)";

            ctx.fillRect(start1, splice.y, end1 - start1, splice_height);
            ctx.fillRect(end1, splice.y + (splice_height / 2), start2 - end1,
            .5);
            ctx.fillRect(start2, splice.y, end2 - start2,
            splice_height);

        }
    },
    searchAjaxData: function(query) {
    matches = new Array();
    //console.log(query)
    for (var i = 0; i < ajaxRequests.length; i++) {
        match = true;
        for (j in query) {
            if (ajaxRequests[i][j] != query[j])
            match = false;
        }
        if (match) matches.push(i)
    }
    return matches;
    },

    summary: function(track, loc) {
        var data = {};
        // console.log(track)
        var pixel_size;
        for (var i = 0; i < selected_tracks.length; i++) {
            var ind = this.searchAjaxData({
                genome: track.additional_params.genome,
                start: loc.start,
                stop: loc.stop,
                //url: 'ajax/get_tracks.php',
                action: track.additional_params.action,
                sample_id: selected_tracks[i]
            })
            if (ind.length == 0)
                return;
            // console.log(ind)
            ind = ind[0]
            pixel_size = ajaxRequests[ind].pixel_size;
            // console.log(ajaxData[ind].data)
            for (j in ajaxData[ind].data) {
            
                if(ajaxData[ind].data[j][0] == undefined) {
                    if(data[j] == undefined) {
                        data[j] = ajaxData[ind].data[j]
                    } else {
                        data[j] += ajaxData[ind].data[j]
                    }
                } else {
                    if(data[j] == undefined) {
                        data[j]  = [];
                        data[j][0] = ajaxData[ind].data[j][0]
                        data[j][1] = ajaxData[ind].data[j][1]
                    } else {
                        data[j][0] += ajaxData[ind].data[j][0]
                        data[j][1] += ajaxData[ind].data[j][1]
                    }
                }
            } 
        }

        eval('this.' + track.func + '(track,loc,{data:data},pixel_size)');
    }



})



 Ext.browser.locationGrid = Ext.extend(Ext.grid.GridPanel, {
    id: 'locationGrid',
    stateful: true,
    initComponent: function() {
        var columns = this.createColumnModel()
        Ext.apply(this, {
            store: new Ext.data.JsonStore(),
            //store,
            id: 'locationGrid',
            columns: columns,
            autoWidth: true,
            stripeRows: true,
            title: '',
            enableHdMenu: false,
            enableDragDrop: false,
            autoExpandColumn: 'location',
            selModel:
            new Ext.grid.RowSelectionModel({
                singleSelect: true
            })
        })

        Ext.browser.locationGrid.superclass.initComponent.apply(this, arguments);

        this.addListener({
            cellclick: {
                fn: this.select_location,
                scope: this
            }
        })

    },
    onRender: function() {
        Ext.browser.locationGrid.superclass.onRender.apply(this, arguments);
        this.addResults(true)
    },
    createColumnModel: function() {
        var columns = new Array();
        for (i = 0; i < config[current_genome].search.columns.length; i++) {
            columns.push(config[current_genome].search.columns[i])
        }
        columns.push({
            header: '<img src="images/cross.png" />',
            width: 30,
            sortable: false,
            dataIndex: 'remove'
        });


        return columns;
    },
    createStore: function() {
        var rows = [];
        for (i in locations) {
            var loc = locations[i];
            rows.push({
                location_id: loc.location_id,
                location: loc.genename,
                remove: '<img src="images/cross.png" />'
            })
        }
        var ccolumns = this.createColumnModel()
        var fields = []
        Ext.each(ccolumns,
        function(x) {
            fields.push({
                mapping: x.dataIndex,
                name: x.dataIndex
            })
        })
        var store = new Ext.data.JsonStore({
            data: {
                root: rows
            },
            storeId: 'locationStore',
            root: 'root',
            idProperty: 'location_id',
            fields: fields
        });

        return store;
    },
    addResults: function(update_location) {

        var store = this.createStore();
        var columns = this.createColumnModel();
        this.reconfigure(store, new Ext.grid.ColumnModel(columns));
        if (this.getStore().getCount() > 0 & update_location) {
            this.select_location(this, this.getStore().getCount() - 1, 0);
            new Ext.util.DelayedTask(function() {
                this.getSelectionModel().selectLastRow();
            },
            this).delay(50)

        }
    },

    select_location: function(g, rowIndex, columnIndex, e) {

        var record = g.getStore().getAt(rowIndex);

        if (columnIndex == 1) {
            this.getStore().remove(this.getStore().getAt(rowIndex))

            sampleGrid.removeColumn(record.json.location_id);
            delete locations[record.json.location_id];

            if (current_loc && current_loc.genename == record.json.location) {
                current_loc = false
            } else {
                g.getSelectionModel().selectRow(g.getStore().find('location', current_loc.genename))
            }
        } else {
            current_loc = cloneObj(locations[record.json.location_id]);
        }
        updateDisplay(true);

    }

})


